package cn.org.rookie.jeesdp.mapper;

import cn.org.rookie.jeesdp.mapper.sql.Wrapper;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * 基础Mapper接口，提供基本的CRUD操作
 *
 * @param <E> 实体类型
 * @param <P> 主键类型
 */
public interface BaseMapper<E, P> {

    /**
     * 插入一条记录
     *
     * @param param 要插入的实体对象
     * @return 影响的行数
     */
    @InsertProvider(type = BaseMapperProvider.class, method = "insert")
    int insert(E param);

    /**
     * 根据主键删除记录
     *
     * @param param 主键值
     * @return 影响的行数
     */
    @DeleteProvider(type = BaseMapperProvider.class, method = "delete")
    int delete(P param);

    /**
     * 根据条件删除记录
     *
     * @param wrapper 查询条件包装器
     * @return 影响的行数
     */
    @DeleteProvider(type = BaseMapperProvider.class, method = "deleteBy")
    int deleteBy(@Param("wrapper") Wrapper wrapper);

    /**
     * 根据主键更新记录
     *
     * @param param 包含更新数据的实体对象
     * @return 影响的行数
     */
    @UpdateProvider(type = BaseMapperProvider.class, method = "update")
    int update(@Param("param") E param);

    /**
     * 根据条件更新记录
     *
     * @param param   包含更新数据的实体对象
     * @param wrapper 查询条件包装器
     * @return 影响的行数
     */
    @UpdateProvider(type = BaseMapperProvider.class, method = "updateBy")
    int updateBy(@Param("param") E param, @Param("wrapper") Wrapper wrapper);

    /**
     * 根据主键查询记录
     *
     * @param param 主键值
     * @return 查询到的实体对象，如果不存在则返回null
     */
    @SelectProvider(type = BaseMapperProvider.class, method = "find")
    E find(P param);

    /**
     * 根据条件查询记录列表
     *
     * @param wrapper 查询条件包装器
     * @return 查询到的实体对象列表
     */
    @SelectProvider(type = BaseMapperProvider.class, method = "findBy")
    List<E> findBy(@Param("wrapper") Wrapper wrapper);

    /**
     * 查询所有记录
     *
     * @return 所有实体对象的列表
     */
    @SelectProvider(type = BaseMapperProvider.class, method = "findAll")
    List<E> findAll();
}
